"""
Agent工厂类
负责创建和配置旅游助手Agent
"""

import logging
from typing import Optional, Dict, Any

from llama_index.core import VectorStoreIndex, Settings
from llama_index.vector_stores.qdrant import QdrantVectorStore
from llama_index.embeddings.dashscope import DashScopeEmbedding
from llama_index.llms.dashscope import DashScope
from qdrant_client import QdrantClient
import os

from ..models.llm_config import LLMConfig
from ..retrieval.retrieval_tool import RetrievalTool
from ..tools.amap_navigation import AmapNavigationTool
from ..utils.logger import setup_logger
from .travel_agent import TravelAgent
from .langgraph_workflow import LangGraphWorkflow


class AgentFactory:
    """Agent工厂类"""
    
    def __init__(self):
        """初始化工厂"""
        self.logger = setup_logger(__name__)
        self.logger.info("Agent工厂初始化完成")
    
    def create_agent(self, config: Optional[LLMConfig] = None) -> TravelAgent:
        """
        创建旅游助手Agent
        
        Args:
            config: LLM配置，如果为None则使用默认配置
            
        Returns:
            配置好的TravelAgent实例
        """
        try:
            self.logger.info("开始创建旅游助手Agent")
            
            # 使用默认配置或提供的配置
            if config is None:
                config = LLMConfig()
            
            # 验证配置
            if not config.validate():
                raise ValueError("LLM配置无效")
            
            # 创建RAG检索工具
            retrieval_tool = self._create_retrieval_tool(config)
            
            # 创建高德地图导航工具
            navigation_tool = self._create_navigation_tool()
            
            # 创建旅游助手Agent
            agent = TravelAgent(retrieval_tool, navigation_tool)
            
            self.logger.info("旅游助手Agent创建完成")
            return agent
            
        except Exception as e:
            self.logger.error(f"创建Agent失败: {e}")
            raise
    
    def create_workflow(self, agent: Optional[TravelAgent] = None) -> LangGraphWorkflow:
        """
        创建LangGraph工作流
        
        Args:
            agent: TravelAgent实例，如果为None则创建新的
            
        Returns:
            配置好的LangGraphWorkflow实例
        """
        try:
            self.logger.info("开始创建LangGraph工作流")
            
            # 如果没有提供Agent，则创建新的
            if agent is None:
                agent = self.create_agent()
            
            # 创建工作流
            workflow = LangGraphWorkflow(agent)
            
            self.logger.info("LangGraph工作流创建完成")
            return workflow
            
        except Exception as e:
            self.logger.error(f"创建工作流失败: {e}")
            raise
    
    def _create_retrieval_tool(self, config: LLMConfig) -> RetrievalTool:
        """创建RAG检索工具"""
        try:
            self.logger.info("创建RAG检索工具")
            
            # 先设置 LlamaIndex 全局 Settings
            self._setup_llm_settings(config)
            
            # 创建Qdrant客户端
            qdrant_client = QdrantClient(
                host=config.qdrant_host,
                port=config.qdrant_port
            )
            
            # 创建向量存储
            vector_store = QdrantVectorStore(
                client=qdrant_client,
                collection_name=config.collection_name
            )
            
            # 创建向量索引
            index = VectorStoreIndex.from_vector_store(vector_store)
            
            # 创建检索工具
            retrieval_tool = RetrievalTool(index, config)
            
            self.logger.info("RAG检索工具创建完成")
            return retrieval_tool
            
        except Exception as e:
            self.logger.error(f"创建RAG检索工具失败: {e}")
            raise
    
    def _create_navigation_tool(self) -> AmapNavigationTool:
        """创建高德地图导航工具"""
        try:
            self.logger.info("创建高德地图导航工具")
            
            navigation_tool = AmapNavigationTool()
            
            self.logger.info("高德地图导航工具创建完成")
            return navigation_tool
            
        except Exception as e:
            self.logger.error(f"创建高德地图导航工具失败: {e}")
            raise
    
    def _setup_llm_settings(self, config: LLMConfig):
        """设置 LlamaIndex 全局 Settings"""
        try:
            # 设置嵌入模型
            embed_model = DashScopeEmbedding(
                model_name=os.getenv("EMBEDDING_MODEL", "text-embedding-v1"),
                api_key=config.api_key
            )
            
            # 设置 LLM
            llm = DashScope(
                model=os.getenv("LLM_MODEL", "qwen-turbo"),
                api_key=config.api_key
            )
            
            # 配置全局设置
            Settings.llm = llm
            Settings.embed_model = embed_model
            
            self.logger.info("LlamaIndex 全局 Settings 配置成功")
            
        except Exception as e:
            self.logger.error(f"配置 LlamaIndex 全局 Settings 失败: {e}")
            raise
    
    def create_complete_system(self, config: Optional[LLMConfig] = None) -> Dict[str, Any]:
        """
        创建完整的系统（Agent + 工作流）
        
        Args:
            config: LLM配置
            
        Returns:
            包含Agent和工作流的字典
        """
        try:
            self.logger.info("创建完整系统")
            
            # 创建Agent
            agent = self.create_agent(config)
            
            # 创建工作流
            workflow = self.create_workflow(agent)
            
            system = {
                "agent": agent,
                "workflow": workflow,
                "config": config or LLMConfig(),
                "status": "ready"
            }
            
            self.logger.info("完整系统创建完成")
            return system
            
        except Exception as e:
            self.logger.error(f"创建完整系统失败: {e}")
            raise
    
    def get_system_status(self, system: Dict[str, Any]) -> Dict[str, Any]:
        """获取系统状态"""
        try:
            agent = system.get("agent")
            workflow = system.get("workflow")
            
            status = {
                "system_status": system.get("status", "unknown"),
                "agent_status": agent.get_agent_status() if agent else {},
                "workflow_available": workflow is not None,
                "config_valid": system.get("config", {}).validate() if system.get("config") else False
            }
            
            return status
            
        except Exception as e:
            self.logger.error(f"获取系统状态失败: {e}")
            return {"error": str(e)}
    
    def test_system(self, system: Dict[str, Any]) -> Dict[str, Any]:
        """测试系统功能"""
        try:
            self.logger.info("开始系统测试")
            
            agent = system.get("agent")
            workflow = system.get("workflow")
            
            test_results = {
                "agent_test": False,
                "workflow_test": False,
                "integration_test": False,
                "errors": []
            }
            
            # 测试Agent
            if agent:
                try:
                    # 简单测试
                    test_query = "你好"
                    response = agent.process_query(test_query)
                    test_results["agent_test"] = response is not None
                except Exception as e:
                    test_results["errors"].append(f"Agent测试失败: {e}")
            
            # 测试工作流
            if workflow:
                try:
                    # 简单测试
                    test_query = "你好"
                    result = workflow.process_query(test_query, "test_thread")
                    test_results["workflow_test"] = result is not None
                except Exception as e:
                    test_results["errors"].append(f"工作流测试失败: {e}")
            
            # 集成测试
            if agent and workflow:
                try:
                    test_query = "成都有什么好玩的？"
                    result = workflow.process_query(test_query, "integration_test")
                    test_results["integration_test"] = result is not None
                except Exception as e:
                    test_results["errors"].append(f"集成测试失败: {e}")
            
            self.logger.info(f"系统测试完成: {test_results}")
            return test_results
            
        except Exception as e:
            self.logger.error(f"系统测试失败: {e}")
            return {"error": str(e)}
